package com.summerbird.mallchat.common.common.utils.sensitiveWord;

import com.summerbird.mallchat.common.common.algorithm.ac.ACTrie;
import com.summerbird.mallchat.common.common.algorithm.ac.MatchResult;
import org.apache.commons.lang3.StringUtils;
import org.springframework.util.CollectionUtils;

import java.util.*;

public final class ACFilter implements SensitiveWordFilter {

    private final static char replace = '*'; // 替代字符
    private static ACTrie ac_trie = null;

    public static ACFilter getInstance() {
        return new ACFilter();
    }

    @Override
    public boolean hasSensitiveWord(String text) {
        if (StringUtils.isBlank(text)) return false;
        return !Objects.equals(filter(text), text);
    }

    /**
     * 敏感词替换
     * @param text 文本
     * @return
     */
    @Override
    public String filter(String text) {
        if (StringUtils.isBlank(text)) {
            return text;
        }
        List<MatchResult> matchResults = ac_trie.matches(text);
        StringBuffer result = new StringBuffer(text);
        // matchResults是按照startIndex排序的，因此可以通过不断更新endIndex最大值的方式算出尚未被替代部分
        int endIndex = 0;
        int startIndex = Integer.MAX_VALUE;
        for (MatchResult matchResult : matchResults) {
            endIndex = Math.max(endIndex, matchResult.getEndIndex());
            startIndex = Math.min(startIndex, matchResult.getStartIndex());
        }
        if(startIndex >= endIndex){
            return text;
        }
        replaceBetween(result, startIndex, endIndex);
        return result.toString();
    }

    private void replaceBetween(StringBuffer result, int startIndex, int endIndex) {
        for(int i = startIndex; i < endIndex; ++i){
            result.setCharAt(i, replace);
        }
    }

    /**
     * 加载敏感词
     * @param words 敏感词数组
     */
    @Override
    public void loadWord(List<String> words) {
        if(CollectionUtils.isEmpty(words)){
            return;
        }
        ac_trie = new ACTrie(words);
    }
}
